package com.ccteam.admin.view.fragments.music

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResult
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.findNavController
import cn.hutool.core.date.DateUtil
import com.ccteam.admin.R
import com.ccteam.admin.REFRESH_REQUEST_KEY
import com.ccteam.admin.databinding.FragmentMusicEditBinding
import com.ccteam.admin.utils.EventObserver
import com.ccteam.admin.utils.LoadMessage
import com.ccteam.admin.view.adapters.SelectArtistAdapter
import com.ccteam.admin.view.adapters.SelectArtistItemClickCallback
import com.ccteam.admin.view.bean.SelectInfoResult
import com.ccteam.admin.view.bean.UploadResult
import com.ccteam.admin.view.fragments.common.SelectFragment
import com.ccteam.admin.view.fragments.common.SelectFragment.Companion.SELECT_ARTIST
import com.ccteam.admin.view.fragments.common.UploadFragment
import com.ccteam.admin.viewmodels.music.MusicEditInfo
import com.ccteam.admin.viewmodels.music.MusicEditViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.orhanobut.logger.Logger
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MusicEditFragment : Fragment() {

    private var _binding: FragmentMusicEditBinding? = null
    private val binding get() = _binding!!

    private val musicEditViewModel by viewModels<MusicEditViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setFragmentResultListener(SelectFragment.SELECT_REQUEST_KEY){ _, bundle ->
            val albumArtistInfo = bundle.getParcelable<SelectInfoResult>(
                SelectFragment.SELECT_RESULT
            )

            albumArtistInfo?.let {
                musicEditViewModel.addSelectArtist(it)
            }
        }

        setFragmentResultListener(UploadFragment.UPLOAD_REQUEST_KEY){ _, bundle ->
            if(bundle.getBoolean(UploadFragment.UPLOAD_REQUEST_KEY)){
                musicEditViewModel.refreshMusicInfo()
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = FragmentMusicEditBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val adapter = SelectArtistAdapter(callback)
        binding.rvSelectArtist.adapter = adapter

        binding.statusView.setRetryClickListener {
            musicEditViewModel.refreshMusicInfo()
        }

        musicEditViewModel.enableEditButton.observe(viewLifecycleOwner, {
            binding.btnEdit.isEnabled = it
        })

        musicEditViewModel.enableDeleteButton.observe(viewLifecycleOwner, {
            binding.btnDelete.isEnabled = it
        })

        musicEditViewModel.loadMessage.observe(viewLifecycleOwner, {
            binding.containerMusicEdit.isVisible = it is LoadMessage.NotLoading
            binding.statusView.changeToLoadingStatus(it is LoadMessage.Loading)
            binding.statusView.changeToErrorStatus(it)
        })

        musicEditViewModel.musicUrl.observe(viewLifecycleOwner, {
            if(it.first.isEmpty()){
                binding.tvBitrateUrl.text = requireContext().getString(R.string.description_bitrate_no)
                binding.btnUploadBitrate.visibility = View.VISIBLE
            } else {
                binding.tvBitrateUrl.text = getString(R.string.description_bitrate_url,it)
                binding.btnUploadBitrate.visibility = View.GONE
            }
        })

        musicEditViewModel.editLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnEdit.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Success){
                Snackbar.make(
                    binding.root,
                    getString(R.string.description_success),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
                setFragmentResult(REFRESH_REQUEST_KEY, bundleOf(REFRESH_REQUEST_KEY to true))
                findNavController().navigateUp()
            } else if(it is LoadMessage.Error){
                Snackbar.make(
                    binding.root,
                    it.errorMessage.description.toString(),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
            }
        })

        musicEditViewModel.deleteLoadMessage.observe(viewLifecycleOwner,EventObserver{
            binding.btnEdit.setLoading(it is LoadMessage.Loading)
            if(it is LoadMessage.Success){
                Snackbar.make(
                    binding.root,
                    getString(R.string.description_success),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
                setFragmentResult(REFRESH_REQUEST_KEY, bundleOf(REFRESH_REQUEST_KEY to true))
                findNavController().navigateUp()
            } else if(it is LoadMessage.Error){
                Snackbar.make(
                    binding.root,
                    it.errorMessage.description.toString(),
                    Snackbar.LENGTH_SHORT
                ).setAnchorView(binding.btnEdit).show()
            }
        })

        binding.btnUploadBitrate.setOnClickListener {
            musicEditViewModel.originMusicInfo?.id?.let { musicId ->
                findNavController().navigate(MusicEditFragmentDirections.actionMusicEditFragmentToUploadAudioFragment(
                    musicId
                ))
            }
        }

        binding.btnSelectArtists.setOnClickListener {
            findNavController().navigate(MusicEditFragmentDirections
                .actionMusicEditFragmentToSelectFragment(SELECT_ARTIST))
        }

        binding.btnDelete.setOnClickListener {
            // 删除该歌曲
            MaterialAlertDialogBuilder(requireContext())
                .setTitle(R.string.description_dialog_delete)

                .setMessage(getString(R.string.description_dialog_delete_music_message,
                    musicEditViewModel.editMusicInfo.value?.name,musicEditViewModel.editMusicInfo.value?.albumName))
                .setNegativeButton(R.string.description_cancel) { _,_ ->

                }
                .setPositiveButton(R.string.description_delete) { _,_ ->
                    musicEditViewModel.deleteMusicInfo()
                }.show()
        }

        binding.editMusicName.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicEditViewModel.setMusicName(text.toString())
                val musicNameSuccess = if(text.toString().isNotEmpty() && text.toString().length in 1..100){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_musicName)
                    false
                }
                musicEditViewModel.setMusicNameSuccess(musicNameSuccess)
            }
        }

        binding.editMusicDuration.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicEditViewModel.setDuration(text.toString())
                val durationSuccess = if(text.toString().isNotEmpty()){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_duration)
                    false
                }
                musicEditViewModel.setDurationSuccess(durationSuccess)
            }
        }

        binding.editMusicYear.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicEditViewModel.setSongYear(text.toString())

                val songYearSuccess = try {
                    val date = DateUtil.format(DateUtil.parse(text),"yyyy-MM-dd")
                    if(date.isNullOrEmpty()){
                        throw NullPointerException()
                    }
                    musicEditViewModel.setSongYear(date)
                    inputLayout.error = null
                    true
                } catch (e: Exception){
                    inputLayout.error = getString(R.string.description_music_edit_error_musicYear)
                    false
                }
                musicEditViewModel.setSongYearSuccess(songYearSuccess)
            }
        }

        binding.editMusicTrack.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicEditViewModel.setTrack(text.toString())
                val trackSuccess = if(text.toString().isNotEmpty()){
                    inputLayout.error = null
                    true
                } else {
                    inputLayout.error = getString(R.string.description_music_edit_error_track)
                    false
                }
                musicEditViewModel.setTrackSuccess(trackSuccess)
            }
        }

        binding.editLrc.addOnEditTextAttachedListener { inputLayout ->
            inputLayout.editText?.doOnTextChanged { text, _, _, _ ->
                musicEditViewModel.setLrc(text.toString())
            }
        }

        binding.btnEdit.setOnClickListener {
            musicEditViewModel.publishMusicInfo()
        }

        musicEditViewModel.selectArtistList.observe(viewLifecycleOwner, {
            adapter.submitList(it)
            adapter.notifyDataSetChanged()
        })

        musicEditViewModel.editMusicInfo.observe(viewLifecycleOwner, {
            updateMusicInfo(it)
        })
    }


    private val callback = object: SelectArtistItemClickCallback {

        /**
         * 当点击删除某一位歌曲歌手时回调
         */
        override fun deleteClick(item: SelectInfoResult) {
            // 请求后端，删除选中的歌手
            musicEditViewModel.removeSelectArtist(item)
        }
    }

    private fun updateMusicInfo(musicInfo: MusicEditInfo) = with(binding){
        tvCurrentAlbum.text = getString(R.string.description_music_edit_album_info,musicInfo.albumName)
        editMusicId.editText?.setText(musicInfo.id)
        editMusicName.editText?.setText(musicInfo.name)
        editMusicDuration.editText?.setText(musicInfo.duration)
        editMusicTrack.editText?.setText(musicInfo.track)
        editMusicYear.editText?.setText(musicInfo.songYear)
        editLrc.editText?.setText(musicInfo.lrc)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        _binding = null
    }
}